var can = document.getElementById('gameCan'),
    ctx = can.getContext('2d'),
    cWidth = ctx.canvas.width,
    cHeight = ctx.canvas.height,
    oSecond = document.getElementsByClassName('second')[0],
    oScore = document.getElementsByClassName('score')[0],
    oStart = document.getElementsByClassName('j-start')[0],
    oPause = document.getElementsByClassName('j-pause')[0],
    oReset = document.getElementsByClassName('j-reset')[0],
    r = 10,//贪吃蛇每个小圆点的半径
    size = r * 2,//蛇的一个高度，相当于直径一样
    t = null,//计时器
    st = null,
    second = 0,
    score = 0,
    bodyNum = 3;//初始化时，给蛇三个小圆点
    // bodyNum = [
    //     { x: 10, y: 10 }, // 蛇尾
    //     { x: 10, y: 30 },
    //     { x: 10, y: 50 } // 蛇头
    // ];

function Circle(x, y, c) {//x，y：X轴和Y轴,一开始可以看成（0,0）点，c：颜色
    this.x = x,
    this.y = y,
    this.c = c
}

Circle.prototype.draw = function() {
    ctx.fillStyle = this.c;
    ctx.beginPath();
    ctx.arc(this.x + r, this.y + r, r, 0, 2 * Math.PI, false);
    ctx.fill();
}

function Snake() {
    this.snakeArr = [];//蛇的身体元素
    this.bodySize = this.snakeArr.length || bodyNum;//蛇初始化时有几个小圆点
    this.dir = 'DOWN';//蛇默认向下移动

    for(var i = 0; i < this.bodySize; i++) {
        this.snakeArr.push(
            new Circle(0, i * r * 2, (i === this.bodySize - 1 ? 'red' : 'green'))
        )
    }
}

Snake.prototype.move = function() {
    var head = this.snakeArr[this.snakeArr.length - 1],//蛇的头部
        snakeArr = this.snakeArr,
        _self = this;

    //每一次绘制前，先清空原来绘制的东西，不用担心性能的问题，canvas在这方面做得是非常的好的
    ctx.clearRect(0, 0, cWidth, cHeight);
    createFood(snakeArr);//调用创建食物
    
    t = setInterval(function() {
        for(var i = 0; i < snakeArr.length; i++) {
            //每一次绘制前，先清空原来绘制的东西，不用担心性能的问题，canvas在这方面做得是非常的好的
            ctx.clearRect(snakeArr[i].x, snakeArr[i].y, size, size);
            //证明不是蛇头的情况下，直接就把arr[i+1]赋值给arr[i]
            if (i !== snakeArr.length - 1) {
               snakeArr[i].x = snakeArr[i + 1].x;
               snakeArr[i].y = snakeArr[i + 1].y;
            } 
        }

        if (_self.dir === 'DOWN') {
            head.y = head.y === cHeight ? 0 : (head.y + size);
            // head.y = head.y === cHeight - size ? 0 : (head.y + size);
        } else if(_self.dir === 'UP') {
            head.y = head.y === -size ? (cHeight - size) 
                                      : (head.y - size);
        } else if(_self.dir === 'RIGHT') {
            // head.x = head.x === (cWidth + size) ? 0 : (head.x + size);
            head.x = head.x === cWidth ? 0 : (head.x + size);
        } else if(_self.dir === 'LEFT') {
            head.x = head.x === -size ? (cWidth - size) 
                                      : (head.x -size);
        }

        for(var i = 0; i < snakeArr.length; i++) {
           //画蛇
           snakeArr[i].draw();
           
           //自己碰撞自己
           if(i !== snakeArr.length - 1) {
               if(head.x === snakeArr[i].x && head.y === snakeArr[i].y) {//证明蛇的头部与身体的某个部分重合了
                   clearInterval(t);
                   t = null;
                   ctx.clearRect(0, 0, cWidth, cHeight);//清空整个蛇的身体
                   alert('GAME OVER');
                   //这一步必须要这样写，不然上面的清除蛇会出问题，只能清除一部分蛇身体
                   s = new Snake();
                   reset();
                   return;
               }
           }
        }

        if(s.foodX === head.x && s.foodY === head.y) {
            var x,
                y;
                
            createFood(snakeArr);

            // 注意，snakeArr的最后一个元素是蛇头，第一个是蛇尾
            if(snakeArr[0].x === snakeArr[1].x) {//x轴相等，说明蛇尾的最后两个是向上或者向下运动
                x = snakeArr[0].x;
                if(snakeArr[0].y > snakeArr[1].y) {//说明蛇尾的最后两个是向上运动的
                    y = snakeArr[0].y + size;
                } else if(snakeArr[0].y < snakeArr[1].y) {//说明蛇尾的最后两个是向下运动的
                    y = snakeArr[0].y - size
                }
            } else if(snakeArr[0].y === snakeArr[1].y) {//y轴相等，说明蛇尾的最后两个是向左或者向右运动
                y = snakeArr[0].y;
                if(snakeArr[0].x > snakeArr[1].x) {//说明蛇尾的最后两个是向左运动的
                    x = snakeArr[0].x + size;
                } else if(snakeArr[0].x < snakeArr[1].x) {//说明蛇尾的最后两个是向右运动的
                    x = snakeArr[0].x - size;
                }
            }

            //吃到后，增加到蛇的身体的最后一个去
            snakeArr.unshift(new Circle(x, y, 'green'));
            //每吃到一个，增加一分
            score++;
            oScore.innerText = score;
        }

    }, 200);
};

var s = new Snake();
// s.move();

document.onkeydown = function() {
    var e = e || window.event,
        code = e.keyCode;

    if (code === 38) {//键盘上键
        s.dir = s.dir !== 'DOWN' ? 'UP' : 'DOWN';
    } else if (code === 40) {//键盘下键
        s.dir = s.dir !== 'UP' ? 'DOWN' : 'UP';
    } else if (code === 37) {//键盘左键
        s.dir = s.dir !== 'RIGHT' ? 'LEFT' : 'RIGHT';
    } else if (code === 39) {//键盘右键
        s.dir = s.dir !== 'LEFT' ? 'RIGHT' : 'LEFT';
    }
};


//创建食物
function createFood(snakeArr) {
    s.foodX = setRandPos().x;
    s.foodY = setRandPos().y;

    for(var i = 0; i < snakeArr.length; i++) {
        //如果食物出现的位置和蛇身体的某部分重合了，那就重新赋一次值
        if (s.foodX === snakeArr[i].x && s.foodY === snakeArr[i].y) {
            s.foodX = setRandPos().x;
            s.foodY = setRandPos().y;
        }
    }

    new Circle(s.foodX, s.foodY, 'yellow').draw();
}

//取600*600区域内，随机出现并且为20的倍数的数,因为canvas画布的宽高就是600*600
function setRandPos() {
    var arr = [];
    for (var i = 0; i < cWidth - size; i++) {
        if (i % size === 0) {
            arr.push(i);
        }
    }
    return {
        //从数组中随机取两个点，去做食物的x，y轴,
        //Math.random():随机数，Math.floor():向下取整，Math.cell():向上取整           
        x: arr[Math.floor(Math.random() * arr.length + 1) - 1],
        y: arr[Math.floor(Math.random() * arr.length + 1) - 1]
    }
}

oStart.onclick = function() { 
    start.call(this);
};

oPause.onclick = function() { 
    pause.call(this);
};

oReset.onclick = function() { 
    reset.call(this);
};

function start() {
    s.move();
    this.disabled = 'disabled';
    st = setInterval(function() {
        second++;
        oSecond.innerText = second;
    }, 1000);
};

function pause() {
    clearInterval(st);
    clearInterval(t);
    oStart.disabled = '';
};

function reset() {
    clearInterval(st);
    clearInterval(t);
    oStart.disabled = '';
    second = 0;
    oSecond.innerText = 0;
    score = 0;
    oScore.innerText = 0;
    ctx.clearRect(0, 0, cWidth, cHeight);

    s = new Snake();
};
























// 递归函数
function digui(n) {
    if (n < 1) {
        return 1;
    }
    return n + digui(n - 1);
}

//斐波拉契数列
function fbl(n) {
    if (n <= 0) {
        return 0;
    }

    if (n <= 2) {
        return 1;
    }

    return fbl(n - 1) + fbl(n - 2);
}

//深拷贝
function deepClone(origin, target) {
    var target = target || {};

    for(var key in origin) {
        if (origin.hasOwnproperty(key)) {
            if (typeof origin[key] === 'object' && origin[key] !== null) {
                if ({}.toString.call(origin[key]) === '[object Array]') {
                    target[key] = [];
                } else {
                    target[key] = {};
                }

                deepClone(origin[key], target[key]);
            } else {
                target[key] = origin[key];
            }
        }
    }

    return target;
}


